using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace GameOverlayWPF
{
    /// <summary>
    /// 热键录制控件，用于捕获用户按下的键盘组合
    /// </summary>
    public class HotkeyRecorder
    {
        private TextBox _textBox;
        private ModifierKeys _modifiers = ModifierKeys.None;
        private Key _mainKey = Key.None;
        private bool _isRecording = false;

        public event EventHandler<HotkeyRecordedEventArgs>? HotkeyRecorded;

        public HotkeyRecorder(TextBox textBox)
        {
            _textBox = textBox ?? throw new ArgumentNullException(nameof(textBox));
            _textBox.PreviewKeyDown += TextBox_PreviewKeyDown;
            _textBox.PreviewKeyUp += TextBox_PreviewKeyUp;
            _textBox.GotFocus += TextBox_GotFocus;
            _textBox.LostFocus += TextBox_LostFocus;
        }

        /// <summary>
        /// 开始录制热键
        /// </summary>
        public void StartRecording()
        {
            _isRecording = true;
            _modifiers = ModifierKeys.None;
            _mainKey = Key.None;
            _textBox.Text = "请按下热键...";
            _textBox.IsReadOnly = false;
            _textBox.Focus();
        }

        /// <summary>
        /// 停止录制热键
        /// </summary>
        public void StopRecording()
        {
            _isRecording = false;
            _textBox.IsReadOnly = true;
        }

        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            if (_isRecording)
            {
                _textBox.Text = "请按下热键...";
            }
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (_isRecording && _mainKey == Key.None)
            {
                _textBox.Text = "未设置";
                StopRecording();
            }
        }

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (!_isRecording)
                return;

            e.Handled = true;

            // 获取当前修饰键
            _modifiers = Keyboard.Modifiers;

            // 获取主键（非修饰键）
            Key key = e.Key;
            
            // 处理系统键
            if (key == Key.System)
                key = e.SystemKey;

            // 如果按下的是修饰键本身，不作为主键
            if (IsModifierKey(key))
            {
                UpdateDisplay();
                return;
            }

            // 如果按下的是Escape，取消录制
            if (key == Key.Escape)
            {
                _mainKey = Key.None;
                _modifiers = ModifierKeys.None;
                _textBox.Text = "已取消";
                StopRecording();
                return;
            }

            // 记录主键
            _mainKey = key;
            UpdateDisplay();

            // 触发热键录制完成事件
            var hotkeySetting = new HotkeySettings
            {
                Modifiers = _modifiers,
                MainKey = _mainKey
            };

            // 验证热键
            if (!hotkeySetting.IsValid())
            {
                string errorMessage;
                if (hotkeySetting.Modifiers == ModifierKeys.None)
                {
                    errorMessage = "无效的热键！\n\n单个按键热键不能使用常用按键（字母、数字、方向键、空格等），\n以避免与正常输入冲突。\n\n建议使用功能键（F1-F12）或组合键。";
                }
                else
                {
                    errorMessage = "无效的热键组合！\n\n主键不能是修饰键本身。";
                }
                
                MessageBox.Show(
                    errorMessage,
                    "热键设置",
                    MessageBoxButton.OK,
                    MessageBoxImage.Warning
                );
                StartRecording();
                return;
            }

            if (hotkeySetting.IsSystemHotkey())
            {
                MessageBox.Show(
                    "该热键是系统保留热键，无法使用！\n\n请选择其他热键组合。",
                    "热键设置",
                    MessageBoxButton.OK,
                    MessageBoxImage.Warning
                );
                StartRecording();
                return;
            }

            // 热键有效，触发事件
            HotkeyRecorded?.Invoke(this, new HotkeyRecordedEventArgs(_modifiers, _mainKey));
            StopRecording();
        }

        private void TextBox_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            if (!_isRecording)
                return;

            e.Handled = true;
        }

        private void UpdateDisplay()
        {
            var text = "";
            
            if (_modifiers.HasFlag(ModifierKeys.Control))
                text += "Ctrl+";
            if (_modifiers.HasFlag(ModifierKeys.Alt))
                text += "Alt+";
            if (_modifiers.HasFlag(ModifierKeys.Shift))
                text += "Shift+";
            if (_modifiers.HasFlag(ModifierKeys.Windows))
                text += "Win+";
            
            if (_mainKey != Key.None && !IsModifierKey(_mainKey))
            {
                text += _mainKey.ToString();
            }
            else
            {
                text += "...";
            }

            _textBox.Text = text;
        }

        private bool IsModifierKey(Key key)
        {
            return key == Key.LeftCtrl || key == Key.RightCtrl ||
                   key == Key.LeftAlt || key == Key.RightAlt ||
                   key == Key.LeftShift || key == Key.RightShift ||
                   key == Key.LWin || key == Key.RWin ||
                   key == Key.System;
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        public void Dispose()
        {
            _textBox.PreviewKeyDown -= TextBox_PreviewKeyDown;
            _textBox.PreviewKeyUp -= TextBox_PreviewKeyUp;
            _textBox.GotFocus -= TextBox_GotFocus;
            _textBox.LostFocus -= TextBox_LostFocus;
        }
    }

    /// <summary>
    /// 热键录制完成事件参数
    /// </summary>
    public class HotkeyRecordedEventArgs : EventArgs
    {
        public ModifierKeys Modifiers { get; }
        public Key MainKey { get; }

        public HotkeyRecordedEventArgs(ModifierKeys modifiers, Key mainKey)
        {
            Modifiers = modifiers;
            MainKey = mainKey;
        }
    }
}
